iT邦幫忙

2026 iThome 鐵人賽

DAY 10
0
AI Engineering

Harness Engineering × Pi Agent 實戰:打造可觀測、可評估的 AI Coding Agent系列 第 10 篇

Day10:規則不必全塞進 Prompt:Skills 如何用漸進揭露控制 Context

  • 分享至 

  • xImage
  •  

AGENTS.md 裝不下的東西

Day8 拆完 AGENTS.md:它會被整份塞進 system prompt,每一輪都跟著送出去。這代表一件事——它有成本上限。

專案規則寫個二三十行沒問題。但如果你想把「資料遷移的完整六步驟」「發版流程」「怎麼寫 migration 檔」全部寫進去,這份檔案會膨脹成幾千個 token,而且每一輪都在付這筆錢,即使今天的任務根本不碰資料遷移。

Skills 就是為了解決這件事。

一個 skill 長什麼樣

一個 skill 就是一個資料夾,裡面有一個 SKILL.md:

taskapp-migration/
└── SKILL.md

SKILL.md 的開頭是 frontmatter,只有兩個必填欄位:

---
name: taskapp-migration
description: Required procedure for any change to taskapp data models ... Use whenever a task changes a taskapp model or asks for a data migration.
---

# taskapp model change and migration

1. schema/models.json — 加欄位、version +1
2. python scripts/gen_models.py
...

description 是整個機制的關鍵,等一下會說為什麼。

Pi 會從這些地方找 skills:全域的 ~/.pi/agent/skills/、~/.agents/skills/;專案的 .pi/skills/、.agents/skills/(這兩個要專案被信任才會載入);npm 套件;設定檔;還有 CLI 的 --skill 參數。量測台用的是 --skill,因為它不受專案信任影響,也不會污染我電腦上的全域設定。

只有描述會進 system prompt

這是 progressive disclosure 的核心。Pi 不會把 SKILL.md 的內容放進 system prompt,只放名稱、描述、檔案位置:

// dist/core/skills.js(節錄)
const lines = [
    "\n\nThe following skills provide specialized instructions for specific tasks.",
    "Use the read tool to load a skill's file when the task matches its description.",
    "When a skill file references a relative path, resolve it against the skill directory ...",
    "",
    "<available_skills>",
];
for (const skill of visibleSkills) {
    lines.push("  <skill>");
    lines.push(`    <name>${escapeXml(skill.name)}</name>`);
    lines.push(`    <description>${escapeXml(skill.description)}</description>`);
    lines.push(`    <location>${escapeXml(skill.filePath)}</location>`);
    lines.push("  </skill>");
}

所以流程是這樣的:

  1. 啟動時,每個 skill 只花掉「名稱+描述+路徑」的 token,通常幾十個。
  2. 模型看到任務跟某個描述對得上,自己決定用 read 工具把那份 SKILL.md 讀進來。
  3. 完整內容這時候才進入 context,而且只有這一個 session 看得到。

這跟 AGENTS.md 的「不管用不用到,每輪都送」形成對比。你可以掛二十個 skill,平常只付二十段描述的錢。

Skills:描述常駐,內容隨選

還有一個容易忽略的細節:skills 只有在 read 工具開著的時候才會被放進 system prompt。原始碼裡是這樣寫的:

if (hasRead && skills.length > 0) {
    prompt += formatSkillsForPrompt(skills);
}

道理很直接——沒有 read 工具,模型根本沒辦法把 skill 讀進來,放描述進去只是浪費 token。這也是一個小小的 harness 設計範例:能力不存在時,不要在 prompt 裡提到它。

便宜,但不保證會被用

progressive disclosure 省 token 的代價是:模型必須自己決定要不要讀。Pi 官方文件對這件事講得很坦白,說模型「不見得總是會這樣做」,必要時得靠 prompt 或 /skill:name 指令強迫它載入。

這就出現一個 AGENTS.md 不會有的失敗模式:

  • AGENTS.md 的規則:一定在模型眼前,模型可能無視,但不會「沒看到」。
  • skill 的內容:模型可能根本沒去讀,那它等於不存在。

所以 skill 的 description 不只是文件,它是觸發條件。寫「處理資料相關的事情」這種描述,模型很難判斷什麼時候該用;寫成「任何會改到 taskapp 資料模型的變更,或要求寫資料遷移時使用」,命中率才會高。

明天要量什麼

因為有「可能沒被讀」這個失敗模式,Day11 的實驗要同時量兩件事,而不是只看成功率:

  1. 有沒有效:同一個資料遷移任務,掛上 skill 跟沒掛,成功率、成本、工具呼叫次數差多少。
  2. 實際載入率:這幾次執行裡,模型真的去 read 那份 SKILL.md 的比例有多高。

第二個數字是關鍵。如果掛了 skill 但成功率沒變,有兩種完全不同的解釋:模型讀了但沒用,或是模型根本沒讀。分不清楚這兩件事,就會把「description 寫得不好」誤判成「skill 這個機制沒用」。量測台從 session 記錄裡撈出每一次 read 的路徑,就是為了回答這個問題。

兩組實驗都會拿掉 AGENTS.md,而且兩組專案裡的 docs/migrations.md 都留著——差別只有「有沒有那份 skill」這一個變數。

明天

Day11 公布數字:Skills 開跟關差多少,以及模型到底有沒有真的去讀那份 SKILL.md。


上一篇
Day9:AGENTS.md 真正改善了什麼?30 次對照實驗的意外答案
下一篇
Day11:Skill 沒有增加新知識,為什麼成本卻少了一半?
系列文
Harness Engineering × Pi Agent 實戰:打造可觀測、可評估的 AI Coding Agent 共 11 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言